package com.lv.common.utils

import android.Manifest
import android.annotation.SuppressLint
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Context.LOCATION_SERVICE
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.Typeface
import android.graphics.drawable.Drawable
import android.location.Address
import android.location.LocationManager
import android.net.Uri
import android.os.Build
import android.provider.Settings
import android.text.*
import android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
import android.text.style.AbsoluteSizeSpan
import android.text.style.StyleSpan
import android.util.Base64
import android.util.Pair
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.core.content.ContextCompat.getSystemService
import com.blankj.utilcode.util.*
import com.google.gson.Gson
import com.google.gson.JsonParser
import com.lv.common.R
import com.lv.common.YgxManager
import com.lv.common.bean.CustomMessageBean
import com.lv.common.network.config.SP_KEY_USER_ID
import com.lv.common.network.config.SP_KEY_USER_REFRESH_TOKEN
import com.lv.common.network.config.SP_KEY_USER_TOKEN
import com.tencent.imsdk.v2.*
import com.tencent.qcloud.tuikit.tuichat.util.ChatMessageBuilder
import com.youth.banner.Banner
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
import java.text.SimpleDateFormat
import java.time.Duration
import java.time.Instant
import java.util.*
import java.util.regex.Pattern


/**
 * 作者： ygx
 * 创建日期：2023/2/11 2:49 PM
 * 签名： 天行健，君子以自强不息；地势坤，君子以厚德载物。
 * -    _              _           _     _   ____  _             _ _
 * -   / \   _ __   __| |_ __ ___ (_) __| | / ___|| |_ _   _  __| (_) ___
 * -  / _ \ | '_ \ / _` | '__/ _ \| |/ _` | \___ \| __| | | |/ _` | |/ _ \
 * - / ___ \| | | | (_| | | | (_) | | (_| |  ___) | |_| |_| | (_| | | (_) |
 * -/_/   \_\_| |_|\__,_|_|  \___/|_|\__,_| |____/ \__|\__,_|\__,_|_|\___/
 * <p>
 * You never know what you can do until you try !
 * ----------------------------------------------------------------
 * 描述：
 */
class YgxUtilsKt {

    companion object {
        fun sendCode(phone: String): String {
            var sa = ""
            var s: String? = ""
            try {
                val substring = phone.substring(5, 11)
                val split = substring.split("")
                sa = ""
                for (i in split.indices) {
                    if (split[i].isEmpty()) {
                        continue
                    }
                    val integer = Integer.valueOf(split[i])
                    val nu = integer + 1
                    sa += if (nu != 10) {
                        nu
                    } else {
                        0
                    }
                }
                s = MyUtils.DoMd5(sa, 2)
            } catch (e: NumberFormatException) {
                throw RuntimeException(e)
            }
            return s
        }

        fun md5String(text: String): String {
            try {
                //获取md5加密对象
                val instance: MessageDigest = MessageDigest.getInstance("MD5")
                //对字符串加密，返回字节数组
                val digest: ByteArray = instance.digest(text.toByteArray())
                var sb = StringBuffer()
                for (b in digest) {
                    //获取低八位有效值
                    var i: Int = b.toInt() and 0xff
                    //将整数转化为16进制
                    var hexString = Integer.toHexString(i)
                    if (hexString.length < 2) {
                        //如果是一位的话，补0
                        hexString = "0$hexString"
                    }
                    sb.append(hexString)
                }
                return sb.toString()

            } catch (e: NoSuchAlgorithmException) {
                e.printStackTrace()
            }

            return ""
        }


        /**
         * 获取当前应用程序的包名。
         *
         * @return 当前应用程序的包名。
         */
        val appPackage: String
            get() = YgxManager.context!!.packageName

        /**
         * 获取当前应用程序的名称。
         * @return 当前应用程序的名称。
         */
        val appName: String
            get() = YgxManager.context!!.resources.getString(YgxManager.context!!.applicationInfo.labelRes)

        /**
         * 获取当前应用程序的版本名。
         * @return 当前应用程序的版本名。
         */
        val appVersionName: String
            get() = YgxManager.context!!.packageManager.getPackageInfo(appPackage, 0).versionName

        /**
         * 获取当前应用程序的版本号。
         * @return 当前应用程序的版本号。
         */
        val appVersionCode: Long
            get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                YgxManager.context!!.packageManager.getPackageInfo(appPackage, 0).longVersionCode
            } else {
                YgxManager.context!!.packageManager.getPackageInfo(
                    appPackage,
                    0
                ).versionCode.toLong()
            }

        /**
         * 获取开眼应用程序的版本名。
         * @return 开眼当前应用程序的版本名。
         */
//    val eyepetizerVersionName: String
//        get() = "6.3.1"

        /**
         * 获取开眼应用程序的版本号。
         * @return 开眼当前应用程序的版本号。
         */
//    val eyepetizerVersionCode: Long
//        get() = 6030012

        /**
         * 获取设备的的型号，如果无法获取到，则返回Unknown。
         * @return 设备型号。
         */
        val deviceModel: String
            get() {
                var deviceModel = Build.MODEL
                if (TextUtils.isEmpty(deviceModel)) {
                    deviceModel = "unknown"
                }
                return deviceModel
            }

        /**
         * 获取设备的品牌，如果无法获取到，则返回Unknown。
         * @return 设备品牌，全部转换为小写格式。
         */
        val deviceBrand: String
            get() {
                var deviceBrand = Build.BRAND
                if (TextUtils.isEmpty(deviceBrand)) {
                    deviceBrand = "unknown"
                }
                return deviceBrand.toLowerCase(Locale.getDefault())
            }

        private var deviceSerial: String? = null

        /**
         * 获取设备的序列号。如果无法获取到设备的序列号，则会生成一个随机的UUID来作为设备的序列号，UUID生成之后会存入缓存，
         * 下次获取设备序列号的时候会优先从缓存中读取。
         * @return 设备的序列号。
         */
        @SuppressLint("HardwareIds")
        fun getDeviceSerial(): String {
            if (deviceSerial == null) {
                var deviceId: String? = null
                val appChannel = getApplicationMetaData("APP_CHANNEL")
                if ("google" != appChannel || "samsung" != appChannel) {
                    try {
                        deviceId = Settings.Secure.getString(
                            YgxManager.context!!.contentResolver,
                            Settings.Secure.ANDROID_ID
                        )
                    } catch (e: Exception) {
                        LogUtils.e("get android_id with error", e)
                    }
                    if (!TextUtils.isEmpty(deviceId) && deviceId!!.length < 255) {
                        deviceSerial = deviceId
                        return deviceSerial.toString()
                    }
                }
//            var uuid = DataStoreUtils.readStringData("uuid", "")
                var uuid = SPStaticUtils.getString("uuid", "")
                if (!TextUtils.isEmpty(uuid)) {
                    deviceSerial = uuid
                    return deviceSerial.toString()
                }
                uuid =
                    UUID.randomUUID().toString().replace("-", "").toUpperCase(Locale.getDefault())
                CoroutineScope(Dispatchers.IO).launch { SPStaticUtils.put("uuid", uuid) }
                deviceSerial = uuid
                return deviceSerial.toString()
            } else {
                return deviceSerial.toString()
            }
        }

        /**
         * 获取资源文件中定义的字符串。
         *
         * @param resId
         * 字符串资源id
         * @return 字符串资源id对应的字符串内容。
         */
        fun getString(resId: Int): String = YgxManager.context!!.resources.getString(resId)

        /**
         * 获取资源文件中定义的字符串。
         *
         * @param resId
         * 字符串资源id
         * @return 字符串资源id对应的字符串内容。
         */
        fun getDimension(resId: Int): Int =
            YgxManager.context!!.resources.getDimensionPixelOffset(resId)

        /**
         * 获取指定资源名的资源id。
         *
         * @param name
         * 资源名
         * @param type
         * 资源类型
         * @return 指定资源名的资源id。
         */
        fun getResourceId(name: String, type: String): Int =
            YgxManager.context!!.resources.getIdentifier(name, type, appPackage)

        /**
         * 获取AndroidManifest.xml文件中，<application>标签下的meta-data值。
         *
         * @param key
         *  <application>标签下的meta-data健
         */
        fun getApplicationMetaData(key: String): String? {
            var applicationInfo: ApplicationInfo? = null
            try {
                applicationInfo = YgxManager.context!!.packageManager.getApplicationInfo(
                    appPackage,
                    PackageManager.GET_META_DATA
                )
            } catch (e: PackageManager.NameNotFoundException) {
                LogUtils.e(e.message, e)
            }
            if (applicationInfo == null) return ""
            return applicationInfo.metaData.getString(key)
        }

        /**
         * 判断某个应用是否安装。
         * @param packageName
         * 要检查是否安装的应用包名
         * @return 安装返回true，否则返回false。
         */
        fun isInstalled(packageName: String): Boolean {
            val packageInfo: PackageInfo? = try {
                YgxManager.context!!.packageManager.getPackageInfo(packageName, 0)
            } catch (e: PackageManager.NameNotFoundException) {
                null
            }
            return packageInfo != null
        }

        /**
         * 获取当前应用程序的图标。
         */
        fun getAppIcon(): Drawable {
            val packageManager = YgxManager.context!!.packageManager
            val applicationInfo = packageManager.getApplicationInfo(appPackage, 0)
            return packageManager.getApplicationIcon(applicationInfo)
        }

        /**
         * 判断手机是否安装了QQ。
         */
        fun isQQInstalled() = isInstalled("com.tencent.mobileqq")

        /**
         * 判断手机是否安装了微信。
         */
        fun isWechatInstalled() = isInstalled("com.tencent.mm")

        /**
         * 判断手机是否安装了微博。
         * */
        fun isWeiboInstalled() = isInstalled("com.sina.weibo")

        fun setImageParams(
            params: ConstraintLayout.LayoutParams,
            imageUrl: String
        ): ConstraintLayout.LayoutParams {
            val width: Int = (ScreenUtils.getScreenWidth() - SizeUtils.dp2px(30.0f)) / 2
            params.width = width
            if (imageUrl
                    .contains("_WH_")
            ) {
                val a = imageUrl.split("_WH_")
                val b = a[1].split("_".toRegex()).toTypedArray()
                val c = b[1].split("\\.".toRegex()).toTypedArray()
                if (c[0] != "0" && b[0] != "0") {
                    params.height = width * c[0].toInt() / b[0].toInt()
                } else {
                    params.height = width
                }
            } else {
                params.height = width
            }
            return params
        }

        /**
         * 更新Token
         */
        fun setAppToken(token: String?, refreshToken: String?) {
            SPStaticUtils.put(SP_KEY_USER_TOKEN, token)
            SPStaticUtils.put(SP_KEY_USER_REFRESH_TOKEN, refreshToken)
        }

        /**
         * 更新Token
         */
        fun setAppToken(token: String?, refreshToken: String?, id: String?) {
            SPStaticUtils.put(SP_KEY_USER_TOKEN, token)
            SPStaticUtils.put(SP_KEY_USER_REFRESH_TOKEN, refreshToken)
            SPStaticUtils.put(SP_KEY_USER_ID, id)
        }

        fun sendMessgeToSelf(accid: String?, phone: String?) {
            val chatTag = SPStaticUtils.getString(Constants.KEY_CHAT_TOKEN, "aaa")
            val s: String = chatTag + "亨富然" + accid + "亨富然" + phone
            val v2TIMOfflinePushInfo = V2TIMOfflinePushInfo()
            v2TIMOfflinePushInfo.ext = "syy".toByteArray()
            v2TIMOfflinePushInfo.desc = "您的账号在另一台设备上登录了"
            // OPPO必须设置ChannelID才可以收到推送消息，这个channelID需要和控制台一致
            v2TIMOfflinePushInfo.setAndroidOPPOChannelID("channel_syy")
//            v2TIMOfflinePushInfo.setAndroidOPPOChannelID("push_channel_syy")
            v2TIMOfflinePushInfo.disablePush(true)
            val customMessageBean = CustomMessageBean("2001", s)
            val data = GsonUtils.toJson(customMessageBean)
            val info =
                ChatMessageBuilder.buildCustomMessage(
                    data,
                    "您的账号在另一台设备上登录了",
                    "syy".toByteArray()
                )
            val v2TIMMessage = info.v2TIMMessage
            v2TIMMessage.isExcludedFromUnreadCount = true
            v2TIMMessage.cloudCustomData = s
            V2TIMManager.getMessageManager().sendMessage(
                v2TIMMessage,
                accid,
                null,
                V2TIMMessage.V2TIM_PRIORITY_DEFAULT,
                false,
                v2TIMOfflinePushInfo,
                object : V2TIMSendCallback<V2TIMMessage?> {
                    override fun onProgress(i: Int) {}
                    override fun onSuccess(v2TIMMessage: V2TIMMessage?) {
                        LogUtil.e("发送信息", "发送信息")
//                        YgxApplication.getInstance().registerPushManually()

                    }

                    override fun onError(i: Int, s: String) {
                        LogUtil.e("s", s)
                    }


                })


        }

        /**
         * 截取字符串
         */
        fun splitString(content: String?, tag: String = ","): Array<String>? {
            return content?.split(tag.toRegex())?.toTypedArray()
        }

        /**
         * 拨打电话（跳转到拨号界面，用户手动点击拨打）
         *
         * @param phoneNum 电话号码
         */
        fun callPhone(context: Context, phoneNum: String) {
            if (phoneNum.length != 11) {
                return
            }
            val intent = Intent(Intent.ACTION_DIAL)
            val data = Uri.parse("tel:$phoneNum")
            intent.data = data
            context.startActivity(intent)
        }

        /**
         * 拨打电话（跳转到拨号界面，用户手动点击拨打）
         *
         * @param phoneNum 电话号码
         */
        fun callAllPhone(context: Context, phoneNum: String) {
//            if (phoneNum.length != 11) {
//                return
//            }
            val intent = Intent(Intent.ACTION_DIAL)
            val data = Uri.parse("tel:$phoneNum")
            intent.data = data
            context.startActivity(intent)
        }

        /**
         * 判断字符串是否是数字
         */
        fun isNumber(str: String?): Boolean {
            val pattern = Pattern.compile("[0-9]*")
            val isNum = pattern.matcher(str)
            return isNum.matches()
        }

        /**
         * 价格
         */
        fun create19PriceSpanTexts(price: String): SpannableStringBuilder {
            val builder = SpannableStringBuilder("¥") //创建SpannableStringBuilder，并添加前面文案
            builder.setSpan(
                AbsoluteSizeSpan(12, true),
                0,
                builder.length,
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
            )
            var spannable: SpannableString? = null
            spannable = SpannableString(price)
            spannable.setSpan(
                AbsoluteSizeSpan(19, true),
                0,
                spannable.length,
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
            )
            spannable.setSpan(
                StyleSpan(Typeface.BOLD), 0, spannable.length,
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
            )
            builder.append(spannable)
            return builder
        }

        fun <T> getObjectList(jsonString: String?, cls: Class<T>?): List<T>? {
            val list: MutableList<T> = ArrayList()
            try {
                val gson = Gson()
                val arry = JsonParser().parse(jsonString).asJsonArray
                for (jsonElement in arry) {
                    list.add(gson.fromJson(jsonElement, cls))
                }
            } catch (e: java.lang.Exception) {
                e.printStackTrace()
            }
            return list
        }

        /**
         * 价格
         */
        fun createPriceSpanTexts(price: String): SpannableStringBuilder {
            val builder = SpannableStringBuilder("¥") //创建SpannableStringBuilder，并添加前面文案
            builder.setSpan(
                AbsoluteSizeSpan(12, true),
                0,
                builder.length,
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
            )
            var spannable: SpannableString? = null
            var spannable1: SpannableString? = null
            if (price.contains(".")) {
                spannable = SpannableString(price.split(".")[0] + ".")
                spannable.setSpan(
                    AbsoluteSizeSpan(15, true),
                    0,
                    spannable.length,
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                )
                spannable.setSpan(
                    StyleSpan(Typeface.BOLD), 0, spannable.length,
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                )
                spannable1 = SpannableString(price.split(".")[1])
                spannable1.setSpan(
                    AbsoluteSizeSpan(12, true),
                    0,
                    spannable1.length,
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                )
                spannable1.setSpan(
                    StyleSpan(Typeface.BOLD), 0, spannable1.length,
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                )
                builder.append(spannable)
                builder.append(spannable1)
            } else {
                spannable = SpannableString(price)
                spannable.setSpan(
                    AbsoluteSizeSpan(15, true),
                    0,
                    spannable.length,
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                )
                spannable.setSpan(
                    StyleSpan(Typeface.BOLD), 0, spannable.length,
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                )
                builder.append(spannable)
            }
            return builder
        }

        /**
         * 价格
         */
        fun createPriceComstomSpanTexts(
            price: String,
            smallSize: Int = 12,
            size: Int
        ): SpannableStringBuilder {
            val builder = SpannableStringBuilder("¥") //创建SpannableStringBuilder，并添加前面文案
            builder.setSpan(
                AbsoluteSizeSpan(smallSize, true),
                0,
                builder.length,
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
            )
            var spannable: SpannableString? = null
            var spannable1: SpannableString? = null
            if (price.contains(".")) {
                spannable = SpannableString(price.split(".")[0] + ".")
                spannable.setSpan(
                    AbsoluteSizeSpan(size, true),
                    0,
                    spannable.length,
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                )
                spannable.setSpan(
                    StyleSpan(Typeface.BOLD), 0, spannable.length,
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                )
                spannable1 = SpannableString(price.split(".")[1])
                spannable1.setSpan(
                    AbsoluteSizeSpan(smallSize, true),
                    0,
                    spannable1.length,
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                )
                spannable1.setSpan(
                    StyleSpan(Typeface.BOLD), 0, spannable1.length,
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                )
                builder.append(spannable)
                builder.append(spannable1)
            } else {
                spannable = SpannableString(price)
                spannable.setSpan(
                    AbsoluteSizeSpan(size, true),
                    0,
                    spannable.length,
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                )
                spannable.setSpan(
                    StyleSpan(Typeface.BOLD), 0, spannable.length,
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                )
                builder.append(spannable)
            }
            return builder
        }

        /**
         * 加水印
         */
        fun addWaterMark(
            resultBitmap: Bitmap,
            widthbigBitmap: Int,
            finalHeight: Int,
            time: Boolean = true
        ): Bitmap {
            var bitmap = ImageUtils.getBitmap(R.drawable.icon_water_bg)
            bitmap = ImageUtils.scale(bitmap, widthbigBitmap, finalHeight)
            bitmap = ImageUtils.addImageWatermark(
                resultBitmap,
                bitmap,
                0, 0,
//            SizeUtils.dp2px(10.0f),
//            SizeUtils.dp2px(10.0f),
                255
            )
            if (time) {
                val date: String =
                    TimeUtil.longNeedTimeByFormat(System.currentTimeMillis(), "yyyy年MM月dd日")
                bitmap = ImageUtils.addTextWatermark(
                    bitmap,
                    date,
                    SizeUtils.sp2px(14.0f),
                    Color.parseColor("#66ffffff"),
                    SizeUtils.dp2px(248.0f).toFloat(),
                    SizeUtils.dp2px(16.0f).toFloat()
                )
            }
            return bitmap
        }

        fun getImageWH(
            imageUrl: String, withItem: Float, isDp: Boolean = true
        ): Triple<Float, Float, Int> {
//            val width: Int = (ScreenUtils.getScreenWidth() - SizeUtils.dp2px(30.0f)) / 2
            var width = 0.0f
            var wh = 0
            if (isDp) {
                width = withItem
            } else {
                width = SizeUtils.dp2px(withItem).toFloat()
            }
            var height = 0.0f
            if (imageUrl
                    .contains("_WH_")
            ) {
                val a = imageUrl.split("_WH_")
                val b = a[1].split("_".toRegex()).toTypedArray()
                val c = b[1].split("\\.".toRegex()).toTypedArray()
                var d = "0"
                if (c[0].contains("?")) {
                    val split = c[0].split("?")
                    d = split[0]
                } else {
                    d = c[0]
                }
                if (d != "0" && b[0] != "0") {
                    height = width * d.toFloat() / b[0].toFloat()
                } else {
                    height = width
                    wh = -1
                }
            } else {
                height = width
                wh = -1
            }
            return Triple(width, height, wh)
        }

        fun getImageWH(
            mWith: Float,
            mHight: Float,
            withItem: Float,
            isDp: Boolean = true,
            isWH: Boolean = false
        ): Triple<Float, Float, Float> {
//            val width: Int = (ScreenUtils.getScreenWidth() - SizeUtils.dp2px(30.0f)) / 2
            var width = 0.0f
            var wh = 0.0f
            if (isDp) {
                width = withItem
            } else {
                width = SizeUtils.dp2px(withItem).toFloat()
            }
            var height = 0.0f
            if (mWith != 0.0f && mHight != 0.0f) {
                height = (mHight * withItem) / mWith
                if (isWH) {//设置最大横竖比16：9
                    if (mWith > mHight) {//横
                        val h = 9 * width / 16
                        if (height < h) {
                            height = h
                        }
                    } else {
                        val h = 16 * width / 9
                        if (height > h) {
                            height = h
                        }
                    }

                }
            } else {
                height = width
                wh = -1.0f
            }

            return Triple(width, height, wh)
        }

        /**
         * @param withItem 宽
         * @param isDp 是否是dp单位
         * @param isWH 是否设置最大横竖比
         * wh=-1为异常结果
         */
        fun getImageWH(
            imageUrl: String, withItem: Int, isDp: Boolean = true, isWH: Boolean = false
        ): Triple<Float, Float, Int> {
//            val width: Int = (ScreenUtils.getScreenWidth() - SizeUtils.dp2px(30.0f)) / 2
            var width = 0.0f
            var wh = 0
            if (isDp) {
                width = withItem.toFloat()
            } else {
                width = SizeUtils.dp2px(withItem.toFloat()).toFloat()
            }
            var height = 0.0f
            if (imageUrl
                    .contains("_WH_")
            ) {
                val a = imageUrl.split("_WH_")
                val b = a[1].split("_".toRegex()).toTypedArray()
                val c = b[1].split("\\.".toRegex()).toTypedArray()
                var d = "0"
                try {
                    if (c[0].contains("?")) {
                        val split = c[0].split("?")
                        d = split[0]
                    } else {
                        d = c[0]
                    }
                    if (d != "0" && b[0] != "0") {
                        height = width * d.toFloat() / b[0].toFloat()
                        if (isWH) {//设置最大横竖比16：9
                            val h = 9 * width / 16
                            if (width > height) {//横
                                if (height < h) {
                                    height = h
                                }
                            } else {
                                val hr = 16 * width / 9
                                if (height > hr) {
                                    height = hr
                                }
                            }

                        }

                    } else {
                        height = width
                        wh = -1
                    }
                } catch (io: Exception) {
                    height = width
                    wh = -1
                }
            } else {
                height = width
                wh = -1
            }
            return Triple(width, height, wh)
        }

        /**
         * 颜色字符串转Int
         */
        fun parseColor(color: String?): Int {
            var colors = color
            if (color.isNullOrEmpty()) {
                colors = "#242424"
            }
            return Color.parseColor(colors)
        }

        fun getColorForString(color: String?): Int {
            if (color.isNullOrEmpty()) {
                return Color.parseColor("#00000000")
            } else {
                if (color.startsWith("#")) {
                    return Color.parseColor(color)
                } else {
                    return Color.parseColor("#$color")
                }
            }
        }

        fun addressTranst(address: Address?): Pair<Double, Double> {
            var mLatitude = address?.latitude ?: 0.0
            var mLongitude = address?.longitude ?: 0.0
            val loactionLatLon = GPSUtil.gps84_To_Gcj02(mLatitude, mLongitude)
            mLatitude = loactionLatLon[0]
            mLongitude = loactionLatLon[1]
            return Pair(mLatitude, mLongitude)
        }

        //判断字符串包含手机号
        fun containsPhoneNumber(input: String): kotlin.Pair<Boolean, List<String>> {
            // 将给定的正则表达式编译到模式中
            val pattern = Pattern.compile("(1[3-9])\\d{9}")
//            val pattern = Pattern.compile("((13[0-9])|(14[0-9])|(15[0-9])|(16[0-9])|(17[0-9])|(18[0-9])|(19[0-9]))\\d{8}");
            // 创建匹配给定输入与此模式的匹配器。
            val matcher = pattern.matcher(input)
            var mNumber = false
            val mPhones = mutableListOf<String>()
            //查找字符串中是否有符合的子字符串
            while (matcher.find()) {
                //查找到符合的即输出
                mNumber = true
                val mPhone = matcher.group()
                mPhones.add(mPhone)
//                LogUtils.e("查询到一个符合的手机号码：" + matcher.group())
            }
            return kotlin.Pair(mNumber, mPhones)
        }

        /**
         *  // 使用示例
         *    val lastDay = getLastDayOfMonth(2023, 3) // 获取2023年3月的最后一天
         *    println("Last day of the month: ${lastDay.get(Calendar.DATE)}")
         */
        fun getLastDayOfMonth(year: Int, month: Int): Int {
            val calendar = Calendar.getInstance()
            calendar.set(year, month - 1, 1) // 将日期设置为指定年月的第一天
            calendar.add(Calendar.MONTH, 1) // 将日期增加一个月，以便到达指定年月的下一个月的第一天
            calendar.add(Calendar.DATE, -1) // 将日期回退一天，到达指定年月的最后一天
            return calendar.get(Calendar.DATE)
        }

        /**
         * 获取xx年x月的最后一天
         * 返回时间戳
         */
        fun getLastTimeStampForMonth(year: String, month: String): String {
            var stamp = ""
            try {
                val mYear = year.toFloat().toInt()
                val mMonth = month.toFloat().toInt()
                val day = getLastDayOfMonth(mYear, mMonth)
                val time = "$year-$month-$day 23:59:59"
                stamp = TimeUtil.dateToStamp(time)
            } catch (e: Exception) {
                stamp = "${TimeUtil.currentTimeMillis()}"
            }
            return stamp
        }

        /**
         * 获取xx年x月的最后一天
         * 返回时间戳
         */
        fun getLastDayForMonth(year: String, month: String): String {
            var stamp = ""
            try {
                val mYear = year.toFloat().toInt()
                val mMonth = month.toFloat().toInt()
                val day = getLastDayOfMonth(mYear, mMonth)
                stamp = "$year-$month-$day"
            } catch (e: Exception) {
                stamp = "$year-$month-01}"
            }
            return stamp
        }

        /**
         * 获取xx年x月x日中月的最后一天
         * 返回时间戳
         */
        fun getLastDayForMonth(time: String): String {
            val ts = time.split("-")
            val year = ts[0]
            val month = ts[1]
            var stamp = ""
            try {
                val mYear = year.toFloat().toInt()
                val mMonth = month.toFloat().toInt()
                val day = getLastDayOfMonth(mYear, mMonth)
                stamp = "$year-$month-$day"
            } catch (e: Exception) {
                stamp = "$year-$month-01}"
            }
            return stamp
        }

        /**
         * 获取xx年x月x日中年的最后一天
         * 返回时间戳
         */
        fun getLastDayForYear(time: String): String {
            val ts = time.split("-")
            val year = ts[0]
            val mMonth = 12
            var stamp = ""
            try {
                val mYear = year.toFloat().toInt()
                val day = getLastDayOfMonth(mYear, mMonth)
                stamp = "$year-$mMonth-$day"
            } catch (e: Exception) {
                stamp = "$year-$mMonth-01}"
            }
            return stamp
        }

        /**
         * 获取xx年x月的最后一天转时间戳
         */
        fun getLastTimeStampForMonth(year: Int, month: Int): String {
            val day = getLastDayOfMonth(year, month)
            val time = "$year-$month-$day 23:59:59"
            return TimeUtil.dateToStamp(time)
        }

        /**
         * 获取xx年x月的第一天转时间戳
         */
        fun getFirstTimeStampForMonth(year: Int, month: Int): String {
            val time = "$year-$month-01 00:00:00"
            return TimeUtil.dateToStamp(time)
        }

        /**
         * 获取xx年x月的第一天转时间戳
         */
        fun getFirstTimeStampForMonth(year: String, month: String): String {
            val time = "$year-$month-01 00:00:00"
            return TimeUtil.dateToStamp(time)
        }

        /**
         * 获取xx年x月的最后一天转时间戳
         * yyyy-MM-dd 或 yyyy-MM  或 yyyy
         */
        fun getLastTimeStamp(time: String): String {
            var stampTime = ""
            try {
                if (time.contains("-")) {
                    val split = time.split("-")
                    if (split.size == 3) {
                        val timeDay = "${split[0]}-${split[1]}-${split[2]} 23:59:59"
                        stampTime = TimeUtil.dateToStamp(timeDay)
                    } else if (split.size == 2) {
                        stampTime = getLastTimeStampForMonth(split[0], split[1])
                    } else {
                        stampTime = getLastTimeStampForMonth(time, "12")
                    }
                } else {
                    stampTime = getLastTimeStampForMonth(time, "12")
                }
            } catch (e: Exception) {
                stampTime = "${TimeUtil.currentTimeMillis()}"
            }
            return stampTime
        }

        /**
         * 获取xx年x月的第一天转时间戳
         * yyyy-MM-dd 或 yyyy-MM  或 yyyy
         */
        fun getFristTimeStamp(time: String): String {
            var stampTime = ""
            try {
                if (time.contains("-")) {
                    val split = time.split("-")
                    if (split.size == 3) {
                        val timeDay = "${split[0]}-${split[1]}-${split[2]} 00:00:00"
                        stampTime = TimeUtil.dateToStamp(timeDay)
                    } else if (split.size == 2) {
                        val timeDay = "${split[0]}-${split[1]}-01 00:00:00"
                        stampTime = TimeUtil.dateToStamp(timeDay)
                    } else {
                        val timeDay = "${time}-01-01 00:00:00"
                        stampTime = TimeUtil.dateToStamp(timeDay)
                    }
                } else {
                    val timeDay = "${time}-01-01 00:00:00"
                    stampTime = TimeUtil.dateToStamp(timeDay)
                }
            } catch (e: Exception) {
                stampTime = "${TimeUtil.currentTimeMillis()}"
            }
            return stampTime
        }

        /**
         * 阿拉伯数字转中文数字
         */
        fun arabicToChinese(number: Int): String {
            val numbers = arrayOf("零", "一", "二", "三", "四", "五", "六", "七", "八", "九")
            val units = arrayOf("", "十", "百", "千", "万")

            val numStr = number.toString()
            var chineseStr = ""

            for (i in numStr.indices) {
                val num = numStr[i].toString().toInt()
                val unit = if (num != 0) units[numStr.length - 1 - i] else ""
                chineseStr += numbers[num] + unit
            }
            chineseStr.replace("零十", "十").replace("零百", "百").replace("零千", "千")
                .replace("零万", "万")
            if (chineseStr.endsWith("零")) {
                chineseStr = chineseStr.substring(0, chineseStr.length - 1)
            }
            if (chineseStr.startsWith("一十")) {
                chineseStr = chineseStr.substring(1, chineseStr.length)
            }
            return chineseStr
        }

        /**
         * 日期比较大小
         * // 使用示例
         * val result = compareDates("2023-01-01", "2023-12-31")
         * when (result) {
         * -1 -> println("第一个日期早于第二个日期")
         * 0 -> println("两个日期相同")
         * 1 -> println("第一个日期晚于第二个日期")
         * }
         */
        fun compareDates(dateStr1: String, dateStr2: String, format: String = "yyyy-MM-dd"): Int {
            val sdf = SimpleDateFormat(format)
            val date1 = sdf.parse(dateStr1)
            val date2 = sdf.parse(dateStr2)

            return date1.compareTo(date2)
        }

        /**
         * 复制文字到剪贴板管理器
         */
        fun clipString(context: Context, mPhone: String, showToset: Boolean = true) {
            //获取剪贴板管理器：
            val cm = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
            // 创建普通字符型ClipData
            val mClipData = ClipData.newPlainText("", mPhone)
            // 将ClipData内容放到系统剪贴板里。
            cm.setPrimaryClip(mClipData)
            if (showToset) {
                showToast("复制成功")
            }
        }

        fun encodeToBase64(input: String): String {
            return Base64.encodeToString(input.toByteArray(), Base64.NO_WRAP)
        }

        fun decodeFromBase64(input: String): String {
            return String(Base64.decode(input, Base64.NO_WRAP))
        }


        fun calculateTimeDifference(timestamp1: Long, timestamp2: Long): String {
            val start = Instant.ofEpochMilli(timestamp1)
            val end = Instant.ofEpochMilli(timestamp2)
            val duration = Duration.between(start, end)

            val days = duration.toDays()
            val hours = duration.toHours() % 24
            val minutes = duration.toMinutes() % 60
//            val seconds = duration.seconds % 60
            if (days == 0L) {
                return "${hours}时${minutes}分"
            } else {
                return "${days}天${hours}时${minutes}分"
            }
        }

        /**
         * 封装Banner时间
         */
        fun parseBannerTime(startup: Int?, defaultTime: Int = 2): Long {
            var time = defaultTime * 1000L
            if (startup != null) {
                if (startup < 60) {
                    time = startup * 1000L
                } else {
                    time = startup * 1L
                }
            }
            return time

        }

        /**
         * 封装Banner时间
         */
        fun parseBannerTime(banner: Banner<*, *>?, startup: Int?, defaultTime: Int = 2) {
            var time = defaultTime * 1000L
            if (startup != null) {
                if (startup < 60) {
                    time = startup * 1000L
                } else {
                    time = startup * 1L
                }
            }
            banner?.setLoopTime(time)
        }

        fun isOPen(context: Context): Boolean {
            val locationManager = context.getSystemService(LOCATION_SERVICE) as LocationManager
            // 通过GPS卫星定位，定位级别可以精确到街（通过24颗卫星定位，在室外和空旷的地方定位准确、速度快）
            val gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
            // 通过WLAN或移动网络(3G/2G)确定的位置（也称作AGPS，辅助GPS定位。主要用于在室内或遮盖物（建筑群或茂密的深林等）密集的地方定位）
            val network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
            return gps || network
        }

        /**
         * 是否有定位权限
         */
        fun checkLocationPermission(context: Context): Boolean {
            return (ContextCompat.checkSelfPermission(
                context,
                Manifest.permission.ACCESS_COARSE_LOCATION
            ) == PackageManager.PERMISSION_GRANTED &&
                    ContextCompat.checkSelfPermission(
                        context,
                        Manifest.permission.ACCESS_FINE_LOCATION
                    ) == PackageManager.PERMISSION_GRANTED)
        }

        /**
         * url 参数转Map
         * @param chart 分割的字符 默认 ?
         */
        fun urlParmasToMap(chart: String = "?", url: String? = ""): Map<String, Any> {
            val map: MutableMap<String, Any> = HashMap()
            if (url.isNullOrEmpty()) {
                return map
            }
            val urlHome = url.split(chart).toTypedArray()
            val parmas = urlHome[1]

            val mData = parmas.split("&").toTypedArray()
            map.clear()
            for (i in mData.indices) {
                val mDatum = mData[i]
                if (!TextUtils.isEmpty(mDatum)) {
                    val split = mDatum.split("=").toTypedArray()
                    if (split.size == 1) {
                        map[split[0]] = ""
                    } else {
                        map[split[0]] = split[1]
                    }
                }
            }
            return map
        }

        /**
         * 价格
         */
        fun create15PriceSpanTexts(price: String): SpannableStringBuilder {
            val builder = SpannableStringBuilder("¥") //创建SpannableStringBuilder，并添加前面文案
            builder.setSpan(
                AbsoluteSizeSpan(12, true),
                0,
                builder.length, SPAN_EXCLUSIVE_EXCLUSIVE
            )
            var spannable: SpannableString? = null
            spannable = SpannableString(price)
            spannable.setSpan(
                AbsoluteSizeSpan(15, true),
                0,
                spannable.length,
                SPAN_EXCLUSIVE_EXCLUSIVE
            )
            spannable.setSpan(
                StyleSpan(Typeface.BOLD), 0, spannable.length,
                SPAN_EXCLUSIVE_EXCLUSIVE
            )
            builder.append(spannable)
            return builder
        }

    }


}